package vip.meet.redisson;

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

import java.util.concurrent.TimeUnit;

/**
 * https://www.jianshu.com/p/f302aa345ca8
 * 互斥性：分布式锁需要保证在不同节点的不同线程的互斥。这是最根本的。
 * 可重入性：同一个节点上的同一个线程如果获取了锁之后也可以再次获取这个锁。
 * 锁超时：和本地锁一样支持锁超时，防止死锁。
 * 高可用：加锁和解锁需要高效，同时也需要保证高可用防止分布式锁失效，可以增加降级。
 * 支持阻塞和非阻塞：和 ReentrantLock 一样支持 lock 和 trylock 以及 tryLock(long timeOut)。
 * 支持公平锁和非公平锁(可选)：公平锁的意思是按照请求加锁的顺序获得锁，非公平锁就相反是无序的。这个一般来说实现的比较少。
 */
public class RedissonSingle {
    public static void main(String[] args) {
        // 构造redisson实现分布式锁必要的Config
        Config config = new Config();
//        config.useSingleServer().setAddress("redis://172.29.1.180:5379").setPassword("a123456").setDatabase(0);
        config.useSingleServer().setAddress("redis://127.0.0.1:6379").setDatabase(0);
// 构造RedissonClient
        RedissonClient redissonClient = Redisson.create(config);
// 设置锁定资源名称
        RLock disLock = redissonClient.getLock("DISLOCK");
        boolean isLock;
        try {
            //尝试获取分布式锁
//            isLock = disLock.tryLock(500, 15000, TimeUnit.MILLISECONDS);
            isLock = disLock.tryLock(500, 15000, TimeUnit.MILLISECONDS);
//            disLock.lock(500L, TimeUnit.MILLISECONDS);
            if (isLock) {
                System.out.println("get lock");
                Thread.sleep(1000);
            }
        } catch (Exception e) {
        } finally {
//            disLock.unlock();
            if(disLock.isLocked()){
                if(disLock.isHeldByCurrentThread()){
                    System.out.println("release lock");
                    disLock.unlock();
                }
            }
        }
    }
}
